/*=====================================================================
  This file is part of a Microsoft SQL Server Shared Source Application.
  Copyright (C) Microsoft Corporation.  All rights reserved.
 
THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
======================================================= */

using System;
using System.Text;
using System.IO;
using System.Xml.Serialization;

namespace Microsoft.SqlServer.BISystems.Tool
{
    /// <summary>
    /// This class is the XML parser. 
    /// </summary>
    public class ASQueryTemplateParser
    {
        /// <summary>
        /// Deserialize the XML template file to ASQueryTemplate object.
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public ASQueryTemplate LoadFromXml(string fileName)
        {
            try
            {
                // Create an XML serializer of type ASQueryTemplate.
                XmlSerializer serializer = new XmlSerializer(typeof(ASQueryTemplate));

                // Add delegates to handle serialization errors.
                serializer.UnknownAttribute += new XmlAttributeEventHandler(SerializeUnknownAttribute);
                serializer.UnknownElement += new XmlElementEventHandler(SerializeUnknownElement);
                serializer.UnknownNode += new XmlNodeEventHandler(SerializeUnknownNode);
                serializer.UnreferencedObject += new UnreferencedObjectEventHandler(SerializeUnreferencedObject);

                // Open the file stream.
                FileStream stream = new FileStream(fileName, FileMode.Open);
                TextReader reader = new StreamReader(stream);

                // Use the Deserialize method to restore to ASQueryTemplate object.
                ASQueryTemplate template = (ASQueryTemplate)serializer.Deserialize(reader);

                return template;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        /// <summary>
        /// Handle errors of unknown attribute.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SerializeUnknownAttribute(object sender, XmlAttributeEventArgs e)
        {
            StringBuilder errMsg = new StringBuilder();
                        
            errMsg.Append("Unknown Attribute: " + e.Attr.Name);
            errMsg.AppendLine();
            
            errMsg.Append("Please check Line Number: " + e.LineNumber + ", Line Position: " + e.LinePosition);
            errMsg.AppendLine();

            errMsg.Append("Expected Attributes are: ");
            errMsg.AppendLine();
            string[] expectedAttrNames = e.ExpectedAttributes.Split(',');
            foreach (string expectedAttrName in expectedAttrNames)
            {
                errMsg.Append(expectedAttrName);
                errMsg.AppendLine();
            }

            throw new Exception(errMsg.ToString());
        }

        /// <summary>
        /// Handle errors of unknown element.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SerializeUnknownElement(object sender, XmlElementEventArgs e)
        {
            StringBuilder errMsg = new StringBuilder();

            errMsg.Append("Unknown Elements: " + e.Element.Name);
            errMsg.AppendLine();

            errMsg.Append("Please check Line Number: " + e.LineNumber + ", Line Position: " + e.LinePosition);
            errMsg.AppendLine();

            errMsg.Append("Expected Elements are: ");
            errMsg.AppendLine();
            string[] expectedElements = e.ExpectedElements.Split(',');
            foreach (string ExpectedElement in expectedElements)
            {
                errMsg.Append(ExpectedElement);
                errMsg.AppendLine();
            }

            throw new Exception(errMsg.ToString());
        }

        /// <summary>
        /// Handle errors of unknown node.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SerializeUnknownNode(object sender, XmlNodeEventArgs e)
        {
            StringBuilder errMsg = new StringBuilder();

            errMsg.Append("Unknown Node: " + e.Name);
            errMsg.AppendLine();
            errMsg.Append("Please check Line Number: " + e.LineNumber + ", Line Position: " + e.LinePosition);
            errMsg.AppendLine();

            throw new Exception(errMsg.ToString());
        }

        /// <summary>
        /// Handle errors of unreferenced object. 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SerializeUnreferencedObject(object sender, UnreferencedObjectEventArgs e)
        {
            throw new Exception("Unreferenced object.");
        }
    }
}
